﻿using System;
using System.Reflection;
using System.Runtime.Serialization;

namespace SessionHunter.Business.SessionReading
{
    /// <summary>
    /// This provides a way to deserialize session information based on currently loaded assemblies
    /// that are loaded using the ReferenceManager
    /// </summary>
    internal class DynamicDeserializer : SerializationBinder
    {
        private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();

        /// <summary>
        /// There are cases where we cannot deserialize the data due to a TargetInvocationException, but we are able to get the type of the
        /// session from BindToType.  So we can return the type, even if we didn't inflate the full object.
        /// </summary>
        public string SessionTypeName
        {
            get;
            set;
        }

        /// <summary>
        /// Binds to the types currently loaded via the ReferenceManager
        /// </summary>
        /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
        /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
        /// <returns>
        /// The type of the object the formatter creates a new instance of.
        /// </returns>
        public override Type BindToType(string assemblyName, string typeName)
        {
            // Keep track of the root type
            if (SessionTypeName == null)
                SessionTypeName = typeName;

            Type assemblyType = null;
            try
            {
                string assemblyShortName = assemblyName.Split(',')[0];
                Assembly[] currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();
                foreach (Assembly assembly in currentAssemblies)
                {
                    if (assembly.FullName.Split(',')[0] == assemblyShortName)
                    {
                        assemblyType = assembly.GetType(typeName);
                        break;
                    }
                }
            }
            catch (System.Exception e)
            {
                logger.Error("DynamicDeserializer error: " + e.Message);
            }
            return assemblyType;
        }
    }

}
